<?php
/**
 * Created by PhpStorm.
 * User: yy
 * Date: 2019/6/25
 * Time: 16:52
 */

namespace app\common\service\airquality;

use app\common\service\CommonService;
use app\common\service\lastWeek\LastWeekControlAnalysisService;
use app\common\service\BaseService;
use think\Db;
use think\facade\Config;
use app\common\service\airquality\AirQualityStationAqiRealtimeDayService;

class AirQualityImproveStatisticsService extends BaseService
{
    /**
     * 空气质量趋势图
     * @author yy by 2019/6/25
     * @param array $param
     * @return array
     */
    public function getAqiTrend($param = [])
    {
        $pollutant_name = str_replace('.', '', strtolower($param['pollutant_name']));
        # 预报值
        $forecast_data = Db::query("select $pollutant_name, DATE_FORMAT(publish_time, '%Y-%m-%d') as date
                        from air_quality_station_aqi_forecast_day
                        where region_id = ? and station_id = ? and is_integer = 1 and publish_time = predict_time and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?",
            [$param['region_id'], $param['station_id'], $param['start_time'], $param['end_time']]);

        # 历史同期值
        $commonService      = new CommonService();
        $history_start_time = $commonService->getHistoryTime($param['start_time']);
        $history_end_time   = $commonService->getHistoryTime($param['end_time']);
        $history_data       = Db::query("select $pollutant_name, DATE_FORMAT(publish_time, '%Y-%m-%d') as date
                        from air_quality_station_aqi_realtime_day
                        where region_id = ? and station_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?",
            [$param['region_id'], $param['station_id'], $history_start_time, $history_end_time]);

        # 实际值
        $real_data = Db::query("select $pollutant_name, DATE_FORMAT(publish_time, '%Y-%m-%d') as date
                    from air_quality_station_aqi_realtime_day
                    where region_id = ? and station_id = ? and DATE_FORMAT(publish_time, '%Y-%m-%d') between ? and ?",
            [$param['region_id'], $param['station_id'], $param['start_time'], $param['end_time']]);

        # 日期补全处理
        $lastWeekControlAnalysisService = new LastWeekControlAnalysisService();
        $forecast_data                  = $lastWeekControlAnalysisService->getAllData($param, $forecast_data, $pollutant_name);
        $history_data                   = $lastWeekControlAnalysisService->getAllData(['start_time' => $history_start_time, 'end_time' => $history_end_time], $history_data, $pollutant_name);
        $real_data                      = $lastWeekControlAnalysisService->getAllData($param, $real_data, $pollutant_name);
        # 比较闰年多出来的天  以平年的天数的为准
        if (count($forecast_data['date']) < count($history_data['date'])) {
            $cha = array_diff($history_data['date'], $forecast_data['date']);//出现在第一个数组中但其他输入数组中没有的值
            foreach ($history_data['date'] as $k => $v) {
                if ($v == $cha[0]) {
                    unset($history_data['data'][0][$k]);
                }
            }
        } elseif (count($history_data['date']) < count($forecast_data['date'])) {
            $cha = array_diff($forecast_data['date'], $history_data['date']);//出现在第一个数组中但其他输入数组中没有的值
            foreach ($forecast_data['date'] as $k => $v) {
                if ($v == $cha[0]) {
                    unset($forecast_data['data'][0][$k]);
                    unset($real_data['data'][0][$k]);
                }
            }
        }
        # 管控值 TODO
        $control_data = [];
        for ($i = 0; $i < count($forecast_data['date']); $i++) {
            $control_data['date'][$i]    = $forecast_data['date'][$i];
            $control_data['data'][0][$i] = '-';
        }
        $result = [
            'date' => $forecast_data['date'],
            'data' => [$forecast_data['data'][0], $history_data['data'][0], $real_data['data'][0], $control_data['data'][0]]
        ];
        return $result;
    }

    /**
     * 行业减排量占比（目前只提供行业id给前台）
     * @author yy by 2019/6/26
     */
    public function getIndustryReduceRate($param = [])
    {
        $data = Db::query("select id,name from basic_industry where delete_time = 0 and id<=4");
        foreach ($data as $k => &$v) {
            $v['value'] = 0;
        }
        return $data;
    }

    /**
     * 行业企业排名（运行浓度、效率、排放量、贡献度）
     * @author yy by 2019/6/26
     * @param array $param
     * @return mixed
     * @throws \MongoDB\Driver\Exception\Exception
     */
    public function getCompanyRank($param = [])
    {
        # 减排前 运行浓度、效率、排放量
        $commonService     = new CommonService();
        $concentration     = $commonService->getRealConcentration($param);        // 指定行业下企业的运行浓度
        $efficiency        = $commonService->getRealEfficiency($param);        // 指定行业下企业的运行效率
        $new_concentration = array_column($concentration, null, 'company_id');
        $new_efficiency    = array_column($efficiency, null, 'company_id');
        $before_data       = [];
        foreach ($new_concentration as $k => $v) {
            $before_data[$k]               = $v;
            $before_data[$k]['efficiency'] = $new_efficiency[$k]['efficiency'];
        }
        $before_data = array_values($before_data);
        # 获取公司简称
        $company = Db::query("select id,short_name,name from basic_company");
        $company = array_column($company, null, 'id'); //指定键值互换
        for ($i = 0; $i < count($before_data); $i++) {
            $before_data[$i]['company_name'] = $company[$before_data[$i]['company_id']]['short_name'] ?: $company[$before_data[$i]['company_id']]['name'];
        }
        # 减排前 贡献度
        $before_contribution = $this->getContribution($param);
        foreach ($before_data as $k => &$v) {
            $v['contribution_value'] = isset($before_contribution[$v['company_id']]) ? $before_contribution[$v['company_id']] : '-';
        }
        # 根据某个值高低进行排序
        $rule = array_column($before_data, 'concentration');//运行浓度
        array_multisort($rule, SORT_DESC, $before_data);
        $arr['operation_concentration']['date']    = array_column($before_data, 'company_name');
        $arr['operation_concentration']['data'][0] = array_column($before_data, 'concentration');
        //减排后
        for ($i = 0; $i < count($arr['operation_concentration']['date']); $i++) {
            $arr['operation_concentration']['data'][1][$i] = '-';
        }

        $rule = array_column($before_data, 'efficiency');//运行效率
        array_multisort($rule, SORT_DESC, $before_data);
        $arr['operating_efficiency']['date']    = array_column($before_data, 'company_name');
        $arr['operating_efficiency']['data'][0] = array_column($before_data, 'efficiency');
        //减排后
        for ($i = 0; $i < count($arr['operating_efficiency']['date']); $i++) {
            $arr['operating_efficiency']['data'][1][$i] = '-';
        }

//        $rule = array_column($before_data, 'emissions');//减排量 TODO
//        array_multisort($rule, SORT_DESC, $before_data);
        $arr['emissions']['date'] = array_column($before_data, 'company_name');
        //减排量不分减排前后
        for ($i = 0; $i < count($arr['emissions']['date']); $i++) {
            $arr['emissions']['data'][0][$i] = '-';
        }
//        $arr['emissions']['data'][0] = array_column($before_data, 'emissions');

        $rule = array_column($before_data, 'contribution_value');//减排前贡献度
        array_multisort($rule, SORT_DESC, $before_data);
        $arr['contribution_value']['date']    = array_column($before_data, 'company_name');
        $arr['contribution_value']['data'][0] = array_column($before_data, 'contribution_value');
        //减排后
        for ($i = 0; $i < count($arr['contribution_value']['date']); $i++) {
            $arr['contribution_value']['data'][1][$i] = '-';
        }

        for ($i = 0; $i < count($arr['operation_concentration']['data'][0]); $i++) {
            $arr['operation_concentration']['data'][0][$i] = round($arr['operation_concentration']['data'][0][$i], 1);//运行浓度减排前
            //$arr['operation_concentration']['data'][1][$i] = round($arr['operation_concentration']['data'][0][$i], 1);//运行浓度减排后
            $arr['operating_efficiency']['data'][0][$i] = round($arr['operating_efficiency']['data'][0][$i] * 100, 1);//运行效率减排前
            //$arr['operating_efficiency']['data'][1][$i]    = round($arr['operating_efficiency']['data'][0][$i] * 100, 1);//运行效率减排后
        }
        $arr['emissions']['data'][0] = $commonService->getRealData($arr['emissions']['data'][0]);//排放量单位转化为吨
        # 减排后 运行浓度、效率、排放量 TODO
        # 减排后 贡献度 TODO
        return $arr;
    }


    /**
     * 获取减排前贡献度
     * @author yy by 2019/6/26
     */
    public function getContribution($param = [])
    {
        $commonService      = new CommonService();
        $newTime            = $commonService->getMongoTime($param);
        $companyIdArr       = $commonService->getCompanyIdArr(0);
        $contribution_name  = $param['is_sulfur'] ? 'SO2' : 'NO2';
        $mongodb_huanxin    = new \MongoDB\Driver\Manager(Config::get('mongodb_url'));
        $document           = [
            'aggregate'    => Config::get('contribution_table_name'),
            'pipeline'     => [
                [
                    '$project' => [
                        'predict_time'        => 1,
                        'publish_time'        => 1,
                        'contribution_name'   => 1,
                        'company_id'          => 1,
                        'industry_id'         => 1,
                        'station_id'          => 1,
                        'region_id'           => 1,
                        'contribution_value'  => 1, //贡献度
                        'contribution_degree' => 1, //贡献值
                        'difference'          => ['$eq' => ['$publish_time', '$predict_time']]
                    ],
                ],
                [
                    '$match' => [
                        'difference'        => true,
                        'industry_id'       => (int)$param['industry_id'],
                        'company_id'        => ['$in' => $companyIdArr],
                        'region_id'         => (int)$param['region_id'],
                        'station_id'        => (int)$param['station_id'],
                        'contribution_name' => strtoupper($contribution_name),
                        'publish_time'      => [
                            '$gte' => $newTime['start_time'],
                            '$lte' => $newTime['end_time'],
                        ],
                    ]
                ],
                [
                    '$group' => [
                        '_id'   => ['company_id' => '$company_id'],
                        'total' => ['$sum' => '$contribution_degree'] //企业贡献值的和
                    ]
                ],
            ],
            'allowDiskUse' => true,
        ];
        $command            = new \MongoDB\Driver\Command($document);
        $rows               = $mongodb_huanxin->executeCommand('huanxin', $command)->toArray();
        $contribution_trend = json_decode(json_encode($rows, 320), true);
        $num                = count($contribution_trend[0]['result']);
        $con                = [];
        if ($num > 0) {
            # 指定污染物的时间区间有效浓度和
            $param['pollutant_name'] = strtolower($contribution_name);
            $concentration_sum       = $commonService->getConcentration($param);
            foreach ($contribution_trend[0]['result'] as $k => $v) {
                $con[$v['_id']['company_id']] = $concentration_sum > 0 ? ($v['total'] / $concentration_sum * 100) : '';
            }
        }
        return $con;
    }

}